package com.credit.service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchDataTransform;
import org.springside.modules.persistence.SearchFilter;

import com.credit.context.CreditServletContext;
import com.credit.entity.CreditCompanyLoan;
import com.credit.entity.CreditGrabOrder;
import com.credit.entity.CreditLiberalLoan;
import com.credit.entity.CreditLoanLog;
import com.credit.entity.CreditLoanOrder;
import com.credit.entity.CreditMessageEntity;
import com.credit.entity.CreditPaymentOrder;
import com.credit.entity.CreditPersonalLoan;
import com.credit.entity.CreditProductInfo;
import com.credit.entity.CreditStudentLoan;
import com.credit.entity.CreditUserInfo;
import com.credit.entity.CreditWorkerLoan;
import com.credit.repository.CreditCompanyLoanDao;
import com.credit.repository.CreditGrabOrderDao;
import com.credit.repository.CreditLiberalLoanDao;
import com.credit.repository.CreditLoanLogDao;
import com.credit.repository.CreditOrderDao;
import com.credit.repository.CreditPersonalLoanDao;
import com.credit.repository.CreditProductInfoDao;
import com.credit.repository.CreditStudentLoanDao;
import com.credit.repository.CreditWorkerLoanDao;
import com.credit.repository.UserDao;
import com.credit.util.CodeValueUtil;
import com.credit.util.LoanLogUtil;
import com.credit.util.ParamsConstant;
import com.credit.util.PointsUtil;

@Component
@Transactional
public class CreditOrderService {
	
	@Autowired
	private CreditOrderDao creditOrderDao;
	@Autowired
	private CreditProductInfoDao creditProductInfoDao;
	@Autowired
	private CreditWorkerLoanDao creditWorkerLoanDao;
	@Autowired
	private CreditPersonalLoanDao creditPersonalLoanDao;
	@Autowired
	private CreditStudentLoanDao creditStudentLoanDao;
	@Autowired
	private CreditLiberalLoanDao creditLiberalLoanDao;
	@Autowired
	private CreditCompanyLoanDao creditCompanyLoanDao;
	@Autowired
	private CreditLoanLogDao creditLoanLogDao;
	@Autowired
	private CreditGrabOrderDao creditGrabOrderDao;
	@PersistenceContext
	protected EntityManager em;
    @Autowired
	private UserService userService;
    @Autowired
    private CreditMessageService creditMessageService;

	public Page<CreditLoanOrder> getListPage(Map<String, Object> searchParams, int pageNumber, Integer pageSize,
			String sortType, Map<String, SearchDataTransform> dataTyps) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, sortType);
		Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
		if (dataTyps != null) {
			SearchDataTransform.dateTypeTransform(filters, dataTyps);
		}
		Specification<CreditLoanOrder> spec = DynamicSpecifications.bySearchFilter(filters.values(), CreditLoanOrder.class);
		return creditOrderDao.findAll(spec, pageRequest);
	}
	
	
	/**
	 * 创建分页请求.
	 */
	private PageRequest buildPageRequest(int pageNumber, int pagzSize, String sortType) {
		Sort sort = null;
		if ("auto".equals(sortType)) {
			sort = new Sort(Direction.DESC, "id");
		} else {
			sort = new Sort(Direction.DESC, sortType);
		}
		return new PageRequest(pageNumber - 1, pagzSize, sort);
	}


	public Page<CreditGrabOrder> getCustomerListPage(Map<String, Object> searchParams, int pageNumber, Integer pageSize,
			String sortType, Map<String, SearchDataTransform> dataTyps) {
		
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, sortType);
		
		Map<String,SearchFilter> filters = SearchFilter.parse(searchParams);
		
		if(dataTyps!=null){
			SearchDataTransform.dateTypeTransform(filters, dataTyps);
		}
		
		Specification<CreditGrabOrder> spec = DynamicSpecifications.bySearchFilter(filters.values(), CreditGrabOrder.class);
		
		return creditGrabOrderDao.findAll(spec, pageRequest);
	}


	/**
	 * 插入单子
	 * @param loanOrder
	 * @param object
	 */
	public CreditLoanOrder create(CreditLoanOrder loanOrder, Object object) {
		
		CreditLoanOrder returnLoadOrder = creditOrderDao.save(loanOrder);
		
		if(object instanceof CreditWorkerLoan){ //上班族贷款
			CreditWorkerLoan creditWorkerLoan = (CreditWorkerLoan) object;
			creditWorkerLoan.setLoanId(returnLoadOrder.getId());
			creditWorkerLoanDao.save(creditWorkerLoan);
		}else if(object instanceof CreditPersonalLoan){//网店/个体户贷款
			CreditPersonalLoan creditPersonalLoan = (CreditPersonalLoan) object;
			creditPersonalLoan.setLoanId(returnLoadOrder.getId());
			creditPersonalLoanDao.save(creditPersonalLoan);
		}else if(object instanceof CreditStudentLoan){//学生贷款
			CreditStudentLoan creditStudentLoan = (CreditStudentLoan) object;
			creditStudentLoan.setLoanId(returnLoadOrder.getId());
			creditStudentLoanDao.save(creditStudentLoan);
		}else if(object instanceof CreditLiberalLoan){//自由职业贷款
			CreditLiberalLoan creditLiberalLoan = (CreditLiberalLoan) object;
			creditLiberalLoan.setLoanId(returnLoadOrder.getId());
			creditLiberalLoanDao.save(creditLiberalLoan);
		}else if(object instanceof CreditCompanyLoan){//企业主贷款
			CreditCompanyLoan creditCompanyLoan = (CreditCompanyLoan) object;
			creditCompanyLoan.setLoanId(returnLoadOrder.getId());
			creditCompanyLoanDao.save(creditCompanyLoan);
		}
		
		//插入日志
		LoanLogUtil.addLoanLog(loanOrder.getId(), loanOrder.getUserId(), ParamsConstant.PROCEEFLAG_USER_MAP.get(loanOrder.getProcessFlag()+"_"+loanOrder.getProcessStatus()), loanOrder.getProcessFlag(), loanOrder.getProcessStatus(),2);
/*		CreditLoanLog creditLoanLog = new CreditLoanLog();
		creditLoanLog.setCreateTime(new Date());
		creditLoanLog.setLoanId(loanOrder.getId());
		creditLoanLog.setProcessFlag(loanOrder.getProcessFlag());
		creditLoanLog.setProcessStatus(loanOrder.getProcessStatus());
		creditLoanLog.setUserId(loanOrder.getUserId());
		creditLoanLog.setAppType(ParamsConstant.appTypeMap.get(request.));
		creditLoanLog.setDescrible(ParamsConstant.PROCEEFLAG_USER_MAP.get(loanOrder.getProcessFlag()+"_"+loanOrder.getProcessStatus()));
		creditLoanLogDao.save(creditLoanLog);*/
		
		return returnLoadOrder;
	}


	public CreditLoanOrder findOrderById(int loanId) {
		
		return creditOrderDao.findOne(Long.valueOf(loanId));
	}


	/**
	 * 单个更新
	 * @param loanOrder
	 */
	public void updateLoanOrder(CreditLoanOrder loanOrder) {
		loanOrder.setUpdateTime(new Date());
		creditOrderDao.save(loanOrder);
	}

	/**
	 * 批量更新
	 * @param list
	 */
	public void batchUpdate(List<CreditLoanOrder> list) {
		
		if(list==null||list.size()<1){
			return;
		}
		
		int size = list.size();
        for (int i = 0; i < size; i++) {
        	CreditLoanOrder creditLoanOrder = list.get(i);
			creditLoanOrder.setOrderType(CodeValueUtil.ORDERTYPE_ORDINARY);
			//creditLoanOrder.setCreditManager(Long.valueOf(0));
			creditLoanOrder.setUpdateTime(new Date());
            em.merge(creditLoanOrder);
            if (i % 50 == 0|| i == (size-1)) {
                em.flush();
                em.clear();
            }
        }
    }
	

	public List<CreditLoanOrder> findOrderListByFlushTime(Integer orderType,Date flushTime) {
		
		return creditOrderDao.findOrderListByFlushTime(orderType,flushTime);
	}


	/**
	 * 审核订单接口(经理端)
	 * @param loanId
	 * @param checkStatus
	 */
	public void checkOrder(long loanId, int processFlag,int processStatus) {
		CreditUserInfo userInfo = CreditServletContext.getUserInfo();
		//我的抢单标记为chechStatus
		CreditGrabOrder grabOrder = creditGrabOrderDao.findByUserIdAndLoanId(userInfo.getId(),loanId);
		grabOrder.setProcessFlag(processFlag);
		grabOrder.setProcessStatus(processStatus);
		grabOrder.setUpdateTime(new Date());
		creditGrabOrderDao.save(grabOrder);
		
		//如果checkStatus = 4 审核成功标记订单为成功
		if(processFlag == CodeValueUtil.PROCESSFLAG_CHECK.intValue() && processStatus==1){
			
			//积分+5
			userInfo.setScore(userInfo.getScore()+5);
			userService.updateUserInfo(userInfo);
			//积分日志
			PointsUtil.addScoreLog(userInfo.getId(), 5, "单子审核成功");
			
			CreditLoanOrder loanOrder = creditOrderDao.findOne(loanId);
			loanOrder.setProcessFlag(processFlag);
			loanOrder.setProcessStatus(processStatus);
			updateLoanOrder(loanOrder);
			
			//消息通知,单子审核结果通知
			CreditMessageEntity message = new CreditMessageEntity();
			message.setCreateTime(new Date());
			message.setDescription("恭献您，您的订单已审核通过");
			message.setTitle("单子审核结果通知");
			message.setUserId(loanOrder.getUserId());
			creditMessageService.addMessage(message);
			
			//放款成功消息
			LoanLogUtil.addLoanLog(loanId, userInfo.getId(), "审核成功", processFlag, processStatus, 1);
			
		}else if(processFlag == CodeValueUtil.PROCESSFLAG_CHECK.intValue() && processStatus==-1){
			CreditLoanOrder loanOrder = creditOrderDao.findOne(loanId);
			loanOrder.setProcessFlag(processFlag);
			loanOrder.setProcessStatus(processStatus);
			updateLoanOrder(loanOrder);
					
			//放款成功消息
			LoanLogUtil.addLoanLog(loanId, userInfo.getId(), "审核失败", processFlag, processStatus, 1);
		}
	}


	public void loan(Long loanId, Integer processFlag,int processStatus, String loanImg) {
		
		CreditUserInfo userInfo = CreditServletContext.getUserInfo();
		//我的抢单标记为loanStatus
		CreditGrabOrder grabOrder = creditGrabOrderDao.findByUserIdAndLoanId(userInfo.getId(),loanId);
		grabOrder.setProcessFlag(processFlag);
		grabOrder.setProcessStatus(processStatus);
		grabOrder.setLoanImg(loanImg);
		grabOrder.setUpdateTime(new Date());
		creditGrabOrderDao.save(grabOrder);
		
		//如果loanStatus = 5 放款成功标记订单为成功
		if(Integer.valueOf(processFlag) == CodeValueUtil.PROCESSFLAG_LOAN&&processStatus==1){
			//积分+5
			userInfo.setScore(userInfo.getScore()+5);
			userService.updateUserInfo(userInfo);
			//积分日志
			PointsUtil.addScoreLog(userInfo.getId(), 5, "单子放款成功");	
			
			CreditLoanOrder loanOrder = creditOrderDao.findOne(loanId);
			loanOrder.setProcessFlag(processFlag);
			loanOrder.setProcessStatus(processStatus);
			updateLoanOrder(loanOrder);
			
			//推送消息
			//消息通知,放款结果通知
			CreditMessageEntity message = new CreditMessageEntity();
			message.setCreateTime(new Date());
			message.setDescription("恭献您，您的订单已放款成功");
			message.setTitle("放款结果通知");
			message.setUserId(loanOrder.getUserId());
			creditMessageService.addMessage(message);
			
			//放款成功消息
			LoanLogUtil.addLoanLog(loanId, userInfo.getId(), "放款成功", processFlag, processStatus, 1);
		}else if(Integer.valueOf(processFlag) == CodeValueUtil.PROCESSFLAG_LOAN&&processStatus==-1){
			CreditLoanOrder loanOrder = creditOrderDao.findOne(loanId);
			loanOrder.setProcessFlag(processFlag);
			loanOrder.setProcessStatus(processStatus);
			updateLoanOrder(loanOrder);
			
			//放款成功消息
			LoanLogUtil.addLoanLog(loanId, userInfo.getId(), "放款失败", processFlag, processStatus, 1);
		}
		
	}


	public void abandon(Long loanId) {
		CreditUserInfo userInfo = CreditServletContext.getUserInfo();
		//我的抢单标记为loanStatus
		CreditGrabOrder grabOrder = creditGrabOrderDao.findByUserIdAndLoanId(userInfo.getId(),loanId);
		grabOrder.setProcessFlag(CodeValueUtil.PROCESSFLAG_ABANDON);
		grabOrder.setProcessStatus(1);
		grabOrder.setUpdateTime(new Date());
		creditGrabOrderDao.save(grabOrder);
		
	}


}
